//
//  HLMenuView.m
//  YueYue
//
//  Created by hulu001 on 2023/6/13.
//

#import "HLMenuView.h"
#import <FrameAccessor/FrameAccessor.h>
#import <objc/message.h>

@interface HLMenuItem ()
@property (strong,  nonatomic) id target;
@property (assign,  nonatomic) SEL action;
@property (copy,    nonatomic) void(^onClickBlock)(void);
@end

@implementation HLMenuItem

+ (HLMenuItem *)itemWithImage:(UIImage *)image title:(NSString *)title target:(id)target action:(SEL)action
{
    HLMenuItem *item = [[HLMenuItem alloc] init];
    [item addUI:image title:title target:target action:action];
    return item;
}

- (void)addUI:(UIImage *)image title:(NSString *)title target:(id)target action:(SEL)action
{
    [self setImage:image forState:UIControlStateNormal];
    [self setTitle:title forState:UIControlStateNormal];
    [self setTitleColor:HLTextColor1 forState:UIControlStateNormal];
    self.titleLabel.font = [UIFont systemFontOfSize:10];
    self.imagePosition = QMUIButtonImagePositionLeft;
    self.spacingBetweenImageAndTitle = 2;
    
    self.target = target;
    self.action = action;
    [self addTarget:self action:@selector(onCLick) forControlEvents:UIControlEventTouchUpInside];
}

- (void)onCLick
{
    ((void (*)(id, SEL))(void *)objc_msgSend)(self.target, self.action);
    if (self.onClickBlock) {
        self.onClickBlock();
    }
}

@end


@interface HLMenuBackgroundView : UIView
@property (copy,    nonatomic) void(^tapBlock)(void);
@end

@implementation HLMenuBackgroundView

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
    UIView *hitView = [super hitTest:point withEvent:event];
    if(hitView == self) {
        if (self.tapBlock) {
            self.tapBlock();
        }
        return nil;
    }
    return hitView;
}

@end


@interface HLMenuView ()

@property (nonatomic, strong) UIView *view;
@property (nonatomic, assign) BOOL isUpAlert;
@property (nonatomic, assign) CGFloat indiractorOffsetX; // 箭头相对menu的X偏移量， menu中心为0
@property (nonatomic, strong) HLMenuBackgroundView *maskView; // 主要用于添加手势，点击消失

@end

@implementation HLMenuView

- (instancetype)init
{
    self = [super init];
    
    if (self) {
        self.backgroundColor = [UIColor.whiteColor colorWithAlphaComponent:0];
        
        self.insets = UIEdgeInsetsMake(12, 12, 17, 12);
        
        self.itemSize = CGSizeMake(60, 40);
        self.indiractorWidth = 20;
        self.indiractorHeight = 10;
        self.horizontalSpacing = 0;
        self.veritalSpacing = 16;
    }
    
    return self;
}

- (void)layoutSubviews
{
    [super layoutSubviews];
    
    for (int i = 0; i < self.items.count; i++) {
        HLMenuItem *item = self.items[i];
        item.viewSize = self.itemSize;
        item.left = self.insets.left + (self.itemSize.width + self.horizontalSpacing) * (i % 6);
        item.top  = self.insets.top + (self.itemSize.height + self.veritalSpacing) * (i / 6);
    }
}


- (void)showMenuFromView:(UIView *)view onView:(UIView * _Nullable)toView
{
    UIView *onView = toView;
    if (!toView) onView = UIApplication.sharedApplication.delegate.window;
    
    for (HLMenuItem *item in self.items) {
        MJWeakSelf
        item.onClickBlock = ^{
            [weakSelf tap:nil];
        };
        [self addSubview:item];
    }
    
    /**
     * 计算大小 先生成一个箭头居中的menu
     */
    CGFloat colum = (self.items.count / 6 >= 1) ? 6 : (self.items.count % 6);
    CGFloat line = (self.items.count-1) / 6 + 1;
    self.width = self.itemSize.width * colum + self.insets.left * 2 + (colum-1) * self.horizontalSpacing;
    self.height = line * self.itemSize.height + self.insets.top + self.insets.bottom + (line-1) * self.veritalSpacing;
    
    CGRect viewRect = [view convertRect:view.bounds toView:onView];
    self.left = CGRectGetMidX(viewRect) - self.width * 0.5;
    self.bottom = CGRectGetMinY(viewRect) - 4;  // 默认向上弹
    
    self.maskView = [[HLMenuBackgroundView alloc] initWithFrame:onView.bounds];
    MJWeakSelf
    self.maskView.tapBlock = ^{
        [weakSelf tap:nil];
    };
    // UIApplication.sharedApplication.delegate.window
    [onView addSubview:self.maskView];
    
    
    /**
     * 上弹是否有效，不能和导航栏重叠
     */
    if (self.top < NavigationBarHeight) {
        // 上弹会超出距离屏幕最低25px的限制，改为向下弹出菜单
        self.isUpAlert = YES;
        self.top = CGRectGetMaxY(viewRect) + 4;
        // 更新菜单内部insets布局
        CGFloat topInset = self.insets.top;
        CGFloat bottomInset = self.insets.bottom;
        self.insets = UIEdgeInsetsMake(bottomInset, self.insets.left, topInset, self.insets.right);
    }
    
    if (self.left < 18) {
        // 需要向右移动
        // indiractorOffsetX反向向左
        self.indiractorOffsetX = self.left - 18;
        self.left = self.left + fabs(self.indiractorOffsetX);
    }
    
    if (self.right > UIApplication.sharedApplication.delegate.window.width - 12) {
        // 需要向左移动
        self.indiractorOffsetX = self.right - (UIApplication.sharedApplication.delegate.window.width - 12);
        self.left = self.left - fabs(self.indiractorOffsetX);
    }
    
    // layout
    [self.maskView addSubview:self];
}

/// 绘制气泡
- (void)drawRect:(CGRect)rect
{
    [super drawRect:rect];
    
    CGContextRef context = UIGraphicsGetCurrentContext();
    
    CGRect rrect = rect;

    CGFloat radius = 11.f;

    CGFloat minx = CGRectGetMinX(rrect),

    midx = CGRectGetWidth(rrect) * 0.5,

    maxx = CGRectGetMaxX(rrect);
    
    // 画笔颜色
    CGContextSetStrokeColorWithColor(context, UIColor.whiteColor.CGColor);
    // 填充颜色
    CGContextSetFillColorWithColor(context, UIColor.whiteColor.CGColor);
    
    if (self.isUpAlert) {
        CGFloat miny = self.indiractorHeight,

        maxy = CGRectGetMaxY(rrect);
        
        // 箭头右边点坐标
        CGContextMoveToPoint(context,
                             self.indiractorOffsetX+ midx+self.indiractorWidth*0.5, // X
                             miny // Y
                             );
        // 箭头顶点坐标
        CGContextAddLineToPoint(context,
                                self.indiractorOffsetX+ midx, // X
                                0 // Y
                                );
        // 箭头左边点坐标
        CGContextAddLineToPoint(context,
                                self.indiractorOffsetX+ midx-self.indiractorWidth*0.5, // X
                                miny //Y
                                );

        CGContextAddArcToPoint(context, minx, miny, minx, maxy, radius);

        CGContextAddArcToPoint(context, minx, maxy, maxx, maxy, radius);

        CGContextAddArcToPoint(context, maxx, maxy, maxx, miny, radius);

        CGContextAddArcToPoint(context, maxx, miny, midx, miny, radius);
    } else {
        CGFloat miny = CGRectGetMinY(rrect),
        maxy = CGRectGetMaxY(rrect)-self.indiractorHeight;
        
        // 箭头右边点坐标
        CGContextMoveToPoint(context,
                             self.indiractorOffsetX + midx +self.indiractorWidth*0.5, // X
                             maxy // Y
                             );
        // 箭头顶点坐标
        CGContextAddLineToPoint(context,
                                self.indiractorOffsetX + midx, // X
                                maxy+self.indiractorHeight // Y
                                );
        // 箭头左边点坐标
        CGContextAddLineToPoint(context,
                                self.indiractorOffsetX + midx -self.indiractorWidth*0.5, // X
                                maxy //Y
                                );

        CGContextAddArcToPoint(context, minx, maxy, minx, miny, radius);

        CGContextAddArcToPoint(context, minx, minx, maxx, miny, radius);

        CGContextAddArcToPoint(context, maxx, miny, maxx, maxx, radius);

        CGContextAddArcToPoint(context, maxx, maxy, midx, maxy, radius);
    }

    CGContextDrawPath(context, kCGPathFill);
    
    // 阴影
    self.layer.shadowColor = [UIColor colorWithRed:211/255.0 green:211/255.0 blue:211/255.0 alpha:0.5].CGColor;
    self.layer.shadowOpacity = 1.0;
    self.layer.shadowOffset = CGSizeMake(0.0f, 2.0f);
    self.layer.shadowRadius = 4;
}

- (void)tap:(id)sender
{
    [self.maskView removeFromSuperview];
}

- (void)tapp:(UIGestureRecognizer *)sender
{
    if (sender.state == UIGestureRecognizerStateEnded) {
        [self tap:nil];
    }
}

@end
